import {
  NButton,
  NCascader,
  NDatePicker,
  NForm,
  NFormItem,
  NGi,
  NGrid,
  NInput,
  NInputNumber,
  NSelect
} from 'naive-ui'
import Icons from '@/components/icons/index.vue'
import { PropType } from 'vue'
import { isFunction } from '@/utils/is'
import { ProtableQueryItem } from '../../type'
import CustomCard from '../custom-card/index.vue'
import './style.less'
import { debounce } from 'lodash-es'

export default defineComponent({
  name: 'QueryForm',
  props: {
    query: {
      type: Array as PropType<ProtableQueryItem[]>,
      default: () => []
    },
    queryData: {
      type: Object,
      default: () => ({})
    },
    collapsed: {
      type: Boolean,
      default: true
    },
    labelWidth: [String, Number] as PropType<number | string | 'auto'>,
    labelAlign: String as PropType<'left' | 'right'>,
    searchBtnText: {
      type: String,
      default: '查询'
    },
    resetBtnText: {
      type: String,
      default: '重置'
    },
    card: {
      type: Boolean,
      default: true
    },
    autoSearch: {
      type: Boolean,
      default: true
    },
    firstLineQueryCount: {
      type: Number,
      default: 3
    }
  },
  emits: ['queryChange', 'search', 'collapsedChange', 'reset'],
  setup(props, { emit, expose }) {
    const form = reactive({})
    const collapsed = ref(props.collapsed)
    const { query, queryData } = toRefs(props)
    const firstLineCount = ref(props.firstLineQueryCount)

    const queryInputs = computed(() => {
      const inputs: ProtableQueryItem[] = []
      query.value.forEach((item, index) => {
        const queryItem: ProtableQueryItem = { ...item }
        if (index === firstLineCount.value) {
          queryItem.span = 24
        }
        inputs.push(queryItem)
      })
      return inputs
    })

    const searchHandleDebounce = debounce(() => {
      nextTick(() => {
        searchHandle()
      })
    }, 500)

    function handleChange(value, item, type?: 'start' | 'end') {
      emit('queryChange', value, item, type)
      if (props.autoSearch) {
        searchHandleDebounce()
      }
    }

    function openHandle() {
      collapsed.value = !collapsed.value
      firstLineCount.value = collapsed.value ? props.firstLineQueryCount : -1
      emit('collapsedChange', collapsed.value)
    }
    function searchHandle(params: Record<string, string> = {}) {
      const searchParams = Object.assign({}, filterNull(form), params)
      emit('search', searchParams)
    }
    function resetHandle() {
      initQuery()
      emit('reset', {})
    }

    function filterNull(obj = {}) {
      const newObj = {}
      Object.keys(obj).forEach((key) => {
        if (obj[key] || obj[key] === false) {
          newObj[key] = obj[key]
        }
      })
      return newObj
    }

    function initQuery() {
      query.value.forEach((item) => {
        if (Array.isArray(item.key)) {
          if (item.type === 'daterange') {
            const [dateStart, dateEnd] = Array.isArray(item.value)
              ? item.value
              : [null, null]
            form[item.key[0]] = dateStart
            form[item.key[1]] = dateEnd
          }
        } else {
          form[item.key] =
            item.value || item.value === false ? item.value : null
        }
      })
    }

    function initQueryData() {
      Object.keys(queryData.value).forEach((key) => {
        form[key] = queryData.value[key] ?? null
      })
    }

    function getSelectOptions(item) {
      return item.dictOptions || useDictData(item.dictCode).value
    }

    watch(
      queryData,
      () => {
        query && initQuery()
        queryData && initQueryData()
      },
      {
        immediate: true
      }
    )

    expose({
      search: searchHandle,
      reset: resetHandle
    })

    return () => {
      return (
        <CustomCard
          is-card={props.card}
          class="pro-table_query-form"
          style={{
            marginBottom: props.card ? '' : '25px',
            marginTop: props.card ? '' : '15px'
          }}
        >
          <NForm
            ref="formRef"
            labelPlacement="left"
            labelAlign={props.labelAlign}
            labelWidth={props.labelWidth}
          >
            <NGrid
              class="query-form-grid"
              xGap={24}
              cols="6 s:6 m:12 l:24 xl:24"
              collapsed={query.value.length > 3 ? collapsed.value : false}
              collapsedRows={1}
              responsive="screen"
            >
              {queryInputs.value.map((item) => {
                return (
                  <>
                    {isFunction(item.render) ? (
                      <NGi span={item.span ?? 6}>
                        <NFormItem
                          label={item.title}
                          labelWidth={item.labelWidth}
                        >
                          {item.render(form)}
                        </NFormItem>
                      </NGi>
                    ) : (
                      <>
                        {item?.type !== 'daterange' ? (
                          <NGi span={item.span ?? 6}>
                            <NFormItem
                              label={item.title}
                              labelWidth={item.labelWidth}
                            >
                              {item.type === 'input' && (
                                <NInput
                                  v-model:value={form[item.key as string]}
                                  placeholder={
                                    item.placeholder ?? '请输入' + item.title
                                  }
                                  onChange={(value) =>
                                    handleChange(value, item)
                                  }
                                  clearable
                                  {...item.props}
                                />
                              )}

                              {item.type === 'inputNumber' && (
                                <NInputNumber
                                  v-model:value={form[item.key as string]}
                                  placeholder={
                                    item.placeholder ?? '请选择' + item.title
                                  }
                                  onUpdate:value={(value) =>
                                    handleChange(value, item)
                                  }
                                  {...item.props}
                                />
                              )}

                              {item.type === 'date' && (
                                <NDatePicker
                                  v-model:formatted-value={
                                    form[item.key as string]
                                  }
                                  valueFormat="yyyy-MM-dd"
                                  type="date"
                                  placeholder={
                                    item.placeholder ?? '请选择' + item.title
                                  }
                                  onUpdate:value={(value) =>
                                    handleChange(value, item)
                                  }
                                  {...item.props}
                                />
                              )}

                              {item.type === 'year' && (
                                <NDatePicker
                                  v-model:formatted-value={
                                    form[item.key as string]
                                  }
                                  valueFormat="yyyy"
                                  type="year"
                                  placeholder={
                                    item.placeholder ?? '请选择' + item.title
                                  }
                                  onUpdate:value={(value) =>
                                    handleChange(value, item)
                                  }
                                  {...item.props}
                                />
                              )}

                              {item.type === 'select' && (
                                <NSelect
                                  v-model:value={form[item.key as string]}
                                  options={getSelectOptions(item)}
                                  multiple={item.multiple}
                                  placeholder={
                                    item.placeholder ?? '请选择' + item.title
                                  }
                                  onUpdate:value={(value) =>
                                    handleChange(value, item)
                                  }
                                  filterable
                                  clearable
                                  {...item.props}
                                />
                              )}

                              {item.type === 'cascader' && (
                                <NCascader
                                  v-model:value={form[item.key as string]}
                                  placeholder={
                                    item.placeholder ?? '请选择' + item.title
                                  }
                                  expandTrigger="click"
                                  options={item.dictOptions as any}
                                  checkStrategy={item.checkStrategy}
                                  showPath={item.showPath}
                                  maxTagCount="responsive"
                                  multiple={item.multiple}
                                  onUpdate:value={(value) =>
                                    handleChange(value, item)
                                  }
                                  filterable
                                  clearable
                                  {...item.props}
                                />
                              )}
                            </NFormItem>
                          </NGi>
                        ) : (
                          <>
                            <NGi span={item.span ?? 6}>
                              <NFormItem
                                label={item.title + '起始日期'}
                                labelWidth={item.labelWidth}
                              >
                                <NDatePicker
                                  v-model:formatted-value={form[item.key[0]]}
                                  valueFormat="yyyy-MM-dd HH:mm:ss"
                                  type="datetime"
                                  placeholder={
                                    item.placeholder ?? '请选择起始日期'
                                  }
                                  onUpdate:value={(value) =>
                                    handleChange(value, item, 'start')
                                  }
                                  clearable
                                  {...item.props}
                                />
                              </NFormItem>
                            </NGi>
                            <NGi span={item.span ?? 6}>
                              <NFormItem
                                label={item.title + '结束日期'}
                                labelWidth={item.labelWidth}
                              >
                                <NDatePicker
                                  v-model:formatted-value={form[item.key[1]]}
                                  valueFormat="yyyy-MM-dd HH:mm:ss"
                                  type="datetime"
                                  placeholder={
                                    item.placeholder ?? '请选择结束日期'
                                  }
                                  onUpdate:value={(value) =>
                                    handleChange(value, item, 'end')
                                  }
                                  clearable
                                  {...item.props}
                                />
                              </NFormItem>
                            </NGi>
                          </>
                        )}
                      </>
                    )}
                  </>
                )
              })}

              <NGi suffix class="suffix" span={6}>
                <div style={{ width: '100%' }}>
                  <NButton type="primary" onClick={() => searchHandle()}>
                    <Icons name="i-search" fill="#fff" />
                    <span style="color: #fff">{props.searchBtnText}</span>
                  </NButton>
                  <NButton
                    style={{ margin: '0 10px' }}
                    onClick={() => resetHandle()}
                  >
                    <i-refresh />
                    {props.resetBtnText}
                  </NButton>

                  {query.value.length > 3 && (
                    <NButton text type="primary" onClick={() => openHandle()}>
                      {collapsed.value ? (
                        <span>
                          展开
                          <i-down />
                        </span>
                      ) : (
                        <span>
                          收起
                          <i-up />
                        </span>
                      )}
                    </NButton>
                  )}
                </div>
              </NGi>
            </NGrid>
          </NForm>
        </CustomCard>
      )
    }
  }
})
